HTTP_FETCH Function
Syntax
Arguments
- settingsPointer
A dot variable containing instructions for the command. Pointer
- hostCharacter
The host (server) from which to download.
Do not include the protocol (HTTP:// or HTTPS://) in the value- portNumeric
Default = 0. The TCP/IP port on the server with which to communicate.
- pageCharacter
Default = "/". The page to request from the server.
- query_stringCharacter
The query string for the request.
- methodCharacter
Default = "GET". The HTTP method to use when making the request (GET, POST, HEAD, OPTIONS, etc).
- protocolCharacter
Default = "HTTP/1.1". The protocol to use for the request.
- user_agentCharacter
Default = "". Sets the User-agent header in the request.
- cookieCharacter
Default = "". Sets the value of the Cookie header.
- bodyCharacter
Default = "". The contents of the HTTP request body.
- refererCharacter
Default = "". Sets the Referer header in the request.
- timeoutNumeric
Default = 45000 (45 seconds). Sets the timeout value, in milliseconds, for the connection.
- headerCharacter
Default = "". One or more headers to send with the request. Allows setting of arbitrary headers. Multiple headers are defined as a cr-lf delimited list. For example:
settings.header = "X-Header: My header" '' specifying multiple headers: settings.header =<<%txt% Content-Type: text/html; charset=UTF-8 X-Custom: My header X-Company: My company %txt%
- SSL_ONLogical
Default = .F.
- ssl_ValidateCert
Default = .T.. If the specified URL starts with "https://", this flag controls whether or not the certificate offered by the server will be validated.
- show_before_sendLogical
Default = .F.. When .T., displays the request before being sent. Useful for debugging. Show_Before_Send is ignored if http_fetch is run from an A5W page.
- SSLCipherListCharacter
Default = httpd_defaultCipherList(). The default SSL cipher list used in the request.
- minTLSLevelNumeric
Default = 1.2. Minimum TLS version to use. You can set this to explicitly use an older TLS version, however this is strongly discouraged.
- Redirects.followLogical
Default = .F.. By default, this function will not follow any server redirects. Set this to .T. to follow redirects. The maximum allowed number of redirects is 20.
Returns
- ResultPointer
A dot variable containing the server's response.
- error_textCharacter
The error message, if any. If no error occurs, error_text will be empty.
- error_codeNumeric
The error number, if any. If no error occurs, error_code will be 0.
- headersCharacter
Response headers. If error_code is 0, the result will contain a dot variable, parsed_headers, with a property representing each response header.
- bodyCharacter
Response body.
- parsed_headersPointer
Contains all the headers in the response split out into individual properties. If an error occurred when trying to communicate with the server, parsed_headers will be empty. parsed_headers will always contain the following properties in addition to the headers in the response:
- http_versionCharacter
The HTTP version used.
- reason_phraseCharacter
A description of the status code.
- status_codeNumeric
The response status code. See Status Codes for a list of status codes.
Description
Sends an HTTP request to a server and retrieves the response
Discussion
The HTTP_FETCH() function sends an HTTP request to a server and receives the response. The function looks to see if a request body has been defined first. If one is found, and no .method has been specified, it uses POST, otherwise it uses GET. If a .method has been specified, that method will always be used, even if it is not a valid HTTP method. Similarly, if a .body is specified and the .method is not POST or PUT, the body is not sent.
If error_code is "0", parsed_response will contain the headers in the result. The parsed headers will contain every header sent in the response, as well as the status_code, reason_phrase, and http_version. The status_code should always be checked when the response is received. The example below shows what headers may be available in the result:
dim settings as P dim settings.host as C = "www.alphasoftware.com" dim settings.page as C = "/" dim result as P result = http_fetch(settings) ? result.error_code = 0 ? result.parsed_headers = AcceptRanges = "none" CacheControl = "private" Connection = "close" ContentLength = "47222" ContentType = "text/html" Date = "Thu, 22 Dec 2016 22:11:23 GMT" http_version = "HTTP/1.1" reason_phrase = "OK" Server = "Microsoft-IIS/8.5" SetCookie = "ASPSESSIONIDQSTBASCQ=KGOAFDNBPPOBEOIJOFEDADFA; path=/" status_code = 200 XPoweredBy = "ASP.NET"
Status code 200 indicates that the page exists. Status code 404 indicates that it does not. Other status codes you may encounter, along with the meanings of each, are documented in Status Codes.
Handling Redirects
When the server responds with a 301, 302, 307, or 308 code, HTTP_GET() does not automatically use the new URL. As of build 8596, developers my optionally specify that redirects should be followed by using the settings.Redirects.follow property. In earlier builds or if automatice redirect handling is not desired, the developer needs to examine result.parsed_headers.status_code, then if appropriate, try the URL provided in result.parsed_headers.location. Refer to HTTP_GET() for an example.
Example: SSL Enabled
The following example demonstrates calling an HTTPS endpoint:
dim settings as P dim settings.host as C = "cat-fact.herokuapp.com" dim settings.page as C = "/facts/" dim settings.ssl_on as L = .t. dim result as P result = http_fetch(settings) if (result.error_code == 0) then if (result.parsed_headers.status_code == 200) ' Fun Feline Fact Fetched showvarjson(result.body) else ' Failed Fetching Feline Facts showvar(result) end if else ' Failed Fetching Feline Facts showvar(result) end if
Example: POSTing JSON Content
This example demonstrates performing a POST operation to submit JSON data to an endpoint.
dim settings as p settings.host = "jsonplaceholder.typicode.com" settings.page = "/posts" settings.method = "POST" settings.ssl_on = .t. settings.header = "Content-Type: application/json; charset=UTF-8" dim body as p body.title = "This is an example" body.body = "It contains some text" body.userId = 1 settings.body = json_generate(body) result = http_fetch(settings) if (result.error_code <> 0) then showvar(result) else if (result.parsed_headers.status_code == 201) then ' API returns 201 (Created) if successful showvarjson(result.body) else showvar(result) end if
Example: Page Availability
The following example tests for the availability of a page:
dim settings as P dim result as P settings.host = "downloads.alphasoftware.com" settings.page = "/books/userguide.pdf" settings.method = "HEAD" result = http_fetch(settings) if (result.error_code <> 0) then ui_msg_box("Error communicating with server. Error code " + result.error_code + ": " + result.error_text) else if (result.parsed_headers.status_code = 200) then a5_show_html(result.body) else ui_msg_box(result.parsed_headers.status_code + ": " + result.parsed_headers.reason_phrase) end if end if
Validation
Validation is applied to the host specified for the HTTP request. If a full URL has been specified as the host name, the validation logic will extract the host name from the URL, allowing the HTTP request to be completed.
Example: Downloading a File
Files are downloaded using the GET method. For example:
dim settings as p settings.host = "www.alphasoftware.com" settings.page = "/hubfs/AlphaAnywhereXbasicGuide.pdf" settings.method = "GET" settings.ssl_on = .t. dim result as p result = http_fetch(settings) if (result.error_code <> 0) then '' ERROR dim errorMsg as c = "Error communicating with server. Error code " + result.error_code + ": " + result.error_text trace.WriteLn(errorMsg,"httpfetch") else if (result.parsed_headers.status_code = 200) then '' sending file to client. dim filename as c = "xbasicGuide.pdf" '' If run in a web application, context.session and context.response '' can be used to return the downloaded file context.session.SaveDataAsFile(filename,result.body) context.response.SendFile(context.session.FormatFileDataURL(filename)) '' !! Important !! '' if file is being downloaded in an Ajax Callback in a component, '' you cannot use context.response. You have to use the '' a5Helper_generateFileDownloadJS() method to generate the JavaScript '' to return to the client to download the file. else dim msg as c = result.parsed_headers.status_code + ": " + result.parsed_headers.reason_phrase trace.WriteLn(msg,"httpfetch") end if end if
The above example assumes the script is running in a web application, such as on an .a5w page. Note, if HTTP_FETCH() is used in an Ajax Callback in a component, you have to use the a5Helper_generateFileDownloadJS() function to generate the required JavaScript to download the file. See Storing Files in Sessions for more info.
See Also